package models;

import com.google.gson.Gson;
import models.constants.DeletedStatus;
import order.AdminOrder;
import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import util.common.ConvertUtil;

import javax.persistence.*;
import java.util.*;

/**
 * Created by liming on 16/7/25.
 * 出库单订单信息
 */
@Entity
@Table(name = "admin_stock_out_order")
public class AdminStockOutOrder extends BaseModel {

    /**
     * 出库单
     */
    @ManyToOne
    @JoinColumn(name = "admin_stock_out_id")
    public AdminStockOut adminStockOut;

    /**
     * 订单Id
     */
    @ManyToOne
    @JoinColumn(name = "admin_order_id")
    public AdminOrder adminOrder;

    /**
     * 出库单中订单状态
     */
    @Column(name = "dismiss")
    public Boolean dismiss = false;

    /**
     * 驳回日期
     */
    @Column(name = "dismiss_date")
    @Temporal(TemporalType.TIMESTAMP)
    public Date dismissDate;

    /**
     * 当时订单客户名称
     */
    @Column(name = "user_name")
    public String userName;

    /**
     * 当时订单联系电话
     */
    @Column(name = "phone")
    public String phone;

    /**
     * 当时区域名称
     */
    @Column(name = "city_name")
    public String cityName;

    /**
     * 当时区域名称
     */
    @Column(name = "community_name")
    public String communityName;

    /**
     * 当时付款金额
     */
    @Column(name = "paymented_amount")
    public Double paymentedAmount;

    /**
     * 根据出库单查询出库订单明细
     *
     * @param outId
     * @return
     */
    public static List<AdminStockOutOrder> findListByOut(long outId,String orderIds) {
        String where;
        String order = " order by cityName,userName,phone,adminOrder.id";
        if(orderIds != null && orderIds.length()>0)
            where = "adminStockOut.id = "+ outId +" and adminOrder.id in (" + ConvertUtil.escapeSql(orderIds) + ") and dismiss = 0";
        else
            where = "adminStockOut.id = "+ outId +" and dismiss = 0";
        return AdminStockOutOrder.find(where + order).fetch();
    }

    /**
     * 出库申请删除
     * @param id
     */
    public final static String SQL_UPDATE_ORDER_STATUS
            = "update admin_order set admin_order_status = ?,admin_stock_out_id = null,admin_stock_out_code = null where admin_stock_out_id = ?";
    public static void deleteByStockOutId(long stockOutId){
        em().createNativeQuery(SQL_UPDATE_ORDER_STATUS).setParameter(1,AdminOrder.OS_NEW).setParameter(2,stockOutId).executeUpdate();
        AdminStockOutOrder.delete("adminStockOut.id = ?",stockOutId);
    }

    /**
     * 出库申请驳回
     * @param stockOutId
     */
    public final static String SQL_UPDATE_STOCK_OUT_ORDER_STATUS
            = "update admin_stock_out_order set dismiss = true,dismissDate=now() where admin_stock_out_id = ?";
    public static void dismissByStockOutId(long stockOutId){
        em().createNativeQuery(SQL_UPDATE_ORDER_STATUS).setParameter(1,AdminOrder.OS_REJECT).setParameter(2,stockOutId).executeUpdate();
        em().createNativeQuery(SQL_UPDATE_STOCK_OUT_ORDER_STATUS).setParameter(1,stockOutId);

    }

    /**
     * 加载订单打印信息
     * @param stockOutId
     * @param stockOutCode
     * @param printIdMap
     * @return
     */
    public final static String SQL_STOCK_OUT_ORDER_ITEM =
            "select a.id as order_id," +
                    "b.id as order_item_id," +
                    "c.name," +
                    "c.spec," +
                    "c.unit," +
                    "c.code," +
                    "ifnull(b.buy_number,0) as buy_number," +
                    "ifnull(b.sale_price,0) as sale_price," +
                    "ifnull(b.amount,0) as amount" +
            " from admin_order a" +
            " left join admin_order_item b on a.id = b.admin_order" +
            " left join goods c on b.goods_id = c.id" +
            " left join product_spec_merchants d on c.serial_id = d.id " +
            " left join product_specs e on d.product_spec_id = e.id  " +
            " left join products f on e.product_id = f.id " +
            " left join admin_product_type g  on f.admin_product_type_id = g.id " +
            "   where b.buy_number!=0 %s " +
            " order by a.id,g.code";
    public static List<AdminOrder> printStockOutOrder(long stockOutId, Map<Long, Integer> printIdMap){
        List<AdminOrder> orderList = new ArrayList<>();
        String selectedOrderId = "";
        String selectedOrderItemSql = null;
        List<AdminStockOutOrder> adminStockOutOrderList = new ArrayList<>();
        Map<Long,AdminOrder> orderMap = new HashMap<>();
        List<Map<String,Object>> orderItemList = null;

        //检查有没有传递过来选中的ID
        if(printIdMap==null){
            selectedOrderItemSql = String.format(SQL_STOCK_OUT_ORDER_ITEM," and a.admin_stock_out_id=" + stockOutId);
        }else{
            //如果有选中id则组装选择ID的筛选条件
            for(Long orderId : printIdMap.keySet())
                selectedOrderId += orderId + ",";
            if(selectedOrderId.length()>0)
                selectedOrderId = selectedOrderId.substring(0,selectedOrderId.length()-1);
            selectedOrderItemSql = String.format(SQL_STOCK_OUT_ORDER_ITEM," and a.id in ("+ ConvertUtil.escapeSql(selectedOrderId) +")");
        }

        //根据上面组装好的条件加载出库订单
        adminStockOutOrderList = AdminStockOutOrder.findListByOut(stockOutId,selectedOrderId);

        //重新组装出库订单,建立订单id对应关系,设置订单打印序列号
        for(int i=1;i<=adminStockOutOrderList.size();i++){
            AdminOrder adminOrder = adminStockOutOrderList.get(i-1).adminOrder;
            orderList.add(adminOrder);
            if(printIdMap == null)
                adminOrder.printOrder = i;
            else
                adminOrder.printOrder = printIdMap.get(adminOrder.id);
            adminOrder.adminOrderItemList = new ArrayList<>();
            orderMap.put(adminOrder.id,adminOrder);
        }

        //加载订单明细数据并且添加到订单中
        Query query = em().createNativeQuery(selectedOrderItemSql);
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        orderItemList = query.getResultList();

        if(orderItemList!=null)
            for(Map<String,Object> item :orderItemList)
                orderMap.get(ConvertUtil.toLong(item.get("order_id"))).adminOrderItemList.add(item);

        //处理订单明细超过12的情况(可以整合到上面的方法上)
        Double pageSize = 12D;
        for (AdminOrder order : orderList){
            if(order.adminOrderItemList.size()>0){
                int printOrderNums = (int)Math.ceil(order.adminOrderItemList.size()/pageSize);
                order.adminOrderItemPages = new ArrayList<>();
                for(int i=0;i<printOrderNums;i++){
                    order.adminOrderItemPages.add(new ArrayList<Map<String, Object>>());
                }

                for(int i=0;i<order.adminOrderItemList.size();i++){
                    int innerItemNums = (int)Math.ceil((i+1)/pageSize);
                    order.adminOrderItemPages.get(innerItemNums-1).add(order.adminOrderItemList.get(i));
                }

                List<Map<String,Object>> lastOrderItemSplitList = order.adminOrderItemPages.get(printOrderNums-1);
                if(lastOrderItemSplitList.size()<pageSize) {
                    for(int i=lastOrderItemSplitList.size();i<pageSize;i++)
                        lastOrderItemSplitList.add(new HashMap<String, Object>());
                }
            }
        }

        return orderList;
    }

}
